package cn.finder.httpcommons.request;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.finder.httpcommons.ApiObject;
import cn.finder.httpcommons.EnumObject;
import cn.finder.httpcommons.attri.JsonIgnore;
import cn.finder.httpcommons.attri.JsonProperty;
import cn.finder.httpcommons.response.ApiResponse;
import cn.finder.httpcommons.utils.Constants;
import cn.finder.httpcommons.utils.DateUtils;
import cn.finder.httpcommons.utils.JsonUtils;

/***
 * 默认的Request实现 主要用于除搜索以外(添加、修改、删除)的请求
 * 
 * @author Administrator
 * 
 * @param <T>
 */
public abstract class DefaultRequest<T extends ApiResponse> extends
		BaseRequest<T> {

	
	
	
	public DefaultRequest() {
		super();
	}


	/***
	 * 额外参数
	 */
	protected Map<String, String> parameters=new HashMap<String, String>();

	public void addParameter(String key, String value) {
		if (this.parameters == null) {
			this.parameters = new HashMap<String, String>();
		}
		this.parameters.put(key, value);

	}

	/***
	 * 获取API 接口 KEY
	 */
	public abstract String apiName();

	/***
	 * 默认 获取请求参数 如果参数值为null 那么转成 ''
	 */
	@SuppressWarnings({ "unchecked", "unused", "rawtypes" })
	public Map<String, String> parameters() {

		Class<? extends DefaultRequest> c = this.getClass();

		Method[] methods = c.getMethods();
		if (methods != null && methods.length > 0) {

			for (Method method : methods) {

				String methodName = method.getName();

				String propName = "";

				if (methodName.startsWith("get") && !methodName.equals("getClass")) {
					JsonIgnore jsonIgnore = method.getAnnotation(JsonIgnore.class);
							
					if (jsonIgnore != null) {
						continue;
					}

					JsonProperty jsonProperty = method
							.getAnnotation(JsonProperty.class);
					if (jsonProperty == null) {

						String nametmp = methodName.substring(3);
						propName = nametmp.substring(0, 1).toLowerCase()
								+ nametmp.substring(1);
					} else {
						if (jsonProperty.name() != null
								&& jsonProperty.name().trim().length() > 0) {
							propName = jsonProperty.name();

						}
					}

					Object propertyValue = null;

					try {
						propertyValue = method.invoke(this);
					} catch (Exception e) {
						e.printStackTrace();
					}

					if (propertyValue == null) {
						propertyValue = "";
					} else if (propertyValue instanceof Date) {
						Date pv = (Date) propertyValue;
						propertyValue = DateUtils.formatDate(pv,
								Constants.DATE_FORMAT);
					} else if (propertyValue instanceof Enum) {
						propertyValue = propertyValue.toString();
					}

					/*
					 * else if (propertyValue instanceof EnumObject<String>) {
					 * propertyValue =
					 * ((EnumObject<String>)propertyValue).toString(); }
					 * 
					 * else if (propertyValue instanceof EnumObject<Integer>) {
					 * propertyValue =
					 * ((EnumObject<Integer>)propertyValue).toString(); } else
					 * if (propertyValue instanceof EnumObject<Float>) {
					 * propertyValue =
					 * ((EnumObject<Float>)propertyValue).toString(); } else if
					 * (propertyValue instanceof EnumObject<Double>) {
					 * propertyValue =
					 * ((EnumObject<Double>)propertyValue).toString(); }
					 */

					else if (propertyValue instanceof EnumObject<?>) {
						propertyValue = ((EnumObject<?>) propertyValue)
								.toString();
					} else if (propertyValue instanceof ApiObject) {

						Map<String, String> p = new HashMap<String, String>();
						parameters(propertyValue, p);
						propertyValue = JsonUtils.objToJsonString(p);
						
					} else if (propertyValue instanceof List) {
						if (propertyValue == null) {
							propertyValue = "";
						} else {
							List tmpPv = (List) propertyValue;
							List<Map<String, String>> listDict = new ArrayList<Map<String, String>>();
							for (int k = 0; k < tmpPv.size(); k++) {
								Map<String, String> p = new HashMap<String, String>();
								Object itemObj = parameters(tmpPv.get(k), p);
								listDict.add(p);
							}
							propertyValue = JsonUtils.objToJsonString(listDict);

						}

					}
					
					 else if (propertyValue instanceof Map) {

						
						propertyValue = JsonUtils.objToJsonString(propertyValue);
						
					} 

					addParameter(propName, propertyValue.toString());

				} else {
					continue;
				}

			}
		}

		return parameters;

	}

	// / <summary>
	// /
	// / </summary>
	// / <param name="obj">对象值</param>
	// / <param name="dict">字段对象</param>
	// / <returns></returns>
	@SuppressWarnings({ "unused", "rawtypes" })
	private Map<String, String> parameters(Object obj, Map<String, String> dict) {

		Method[] methods = obj.getClass().getMethods();
		if (methods != null && methods.length > 0) {

			for (Method method : methods) {

				String methodName = method.getName();

				String propName = "";

				if (methodName.startsWith("get")) {
					JsonIgnore jsonIgnore = method
							.getAnnotation(JsonIgnore.class);
					if (jsonIgnore != null) {
						continue;
					}

					JsonProperty jsonProperty = method
							.getAnnotation(JsonProperty.class);
					if (jsonProperty == null) {

						String nametmp = methodName.substring(3);
						propName = nametmp.substring(0, 1).toLowerCase()
								+ nametmp.substring(1);
					} else {
						if (jsonProperty.name() != null
								&& jsonProperty.name().trim().length() > 0) {
							propName = jsonProperty.name();

						}
					}

					Object propertyValue = null;

					try {
						propertyValue = method.invoke(obj);
					} catch (Exception e) {
						e.printStackTrace();
					}

					if (propertyValue == null) {
						propertyValue = "";
					}

					else if (propertyValue instanceof Date) {
						Date pv = (Date) propertyValue;
						propertyValue = DateUtils.formatDate(pv,
								Constants.DATE_FORMAT);
					}

					/*
					 * else if (propertyValue is EnumObject<String>) {
					 * propertyValue = (propertyValue as
					 * EnumObject<String>).ToString(); }
					 * 
					 * else if (propertyValue is EnumObject<int>) {
					 * propertyValue = (propertyValue as
					 * EnumObject<int>).ToString(); } else if (propertyValue is
					 * EnumObject<float>) { propertyValue = (propertyValue as
					 * EnumObject<float>).ToString(); } else if (propertyValue
					 * is EnumObject<double>) { propertyValue = (propertyValue
					 * as EnumObject<double>).ToString(); }
					 */
					/*
					 * else if (propertyValue is ApiObject) {
					 * 
					 * Map<String, String> p = new Dictionary<String, String>();
					 * 
					 * propertyValue = GetParameters(propertyValue, p);
					 * 
					 * }
					 */

					else if (propertyValue instanceof EnumObject<?>) {
						propertyValue = ((EnumObject<?>) propertyValue)
								.toString();
					} else if (propertyValue instanceof ApiObject) {

						Map<String, String> p = new HashMap<String, String>();

						propertyValue = parameters(propertyValue, p);
					} else if (propertyValue instanceof List) {
						// propertyValue =
						// JsonConvert.ExportToString(propertyValue);
						if (propertyValue == null) {
							propertyValue = "";
						} else {

							List tmpPv = (List) propertyValue;
							List<Map<String, String>> listDict = new ArrayList<Map<String, String>>();
							for (int k = 0; k < tmpPv.size(); k++) {
								Map<String, String> p = new HashMap<String, String>();
								Object itemObj = parameters(tmpPv.get(k), p);
								listDict.add(p);
							}
							propertyValue = JsonUtils.objToJsonString(listDict);
						}

					}

					dict.put(propName, propertyValue.toString());

				}
			}
		}
		
		return parameters;
	}

	

	
	
	public abstract void validate();
	

	
}
